﻿/*
 *  RacerLib - XNA Racing Game Level and Tile Management Library
 * 
 *  Copyright (C) 2009 Sebastian Schäfer
 *  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;

namespace gdv.VCPR.Racer
{
    /// <summary>
    /// A local trackserver that implements the ITrackServer interface
    /// </summary>
    public class TrackServerLocal: ITrackServer
    {
        private String path = ".";
        /// <summary>
        /// The base path for tracks
        /// </summary>
        public String Path { 
            get 
            { 
                return path; 
            } 
            set 
            { 
                setNewPath(value); 
            } 
        }

        private bool scanRecusive = false;
        /// <summary>
        /// Scan in subdirectories
        /// </summary>
        public bool ScanRecursive { 
            get { 
                return scanRecusive; 
            } 
            set { 
                if (scanRecusive != value) 
                { 
                    scanRecusive = value; Rescan(); 
                } 
            } 
        }
        private Collection<Track> db;

        /// <summary>
        /// Create a new instance with given basepath
        /// </summary>
        /// <param name="path">The basepath</param>
        public TrackServerLocal(String path)
        {
            db = new Collection<Track>();
            setNewPath(path);
        }

        private void setNewPath(String path_)
        {
            path = path_;
            Rescan();
        }

        /// <summary>
        /// Rebuild the track database, searching for .trk and .xml files
        /// </summary>
        public void Rescan()
        {
            String[] files = Directory.GetFiles(path, "*.trk", scanRecusive? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            Track track = null;
            foreach (String fname in files)
            {
                try
                {
                    track = Track.Load(fname);
                    if (!db.Contains(track))
                        db.Add(track);
                }
                catch (Exception)
                {
//                    System.Console.WriteLine("Coudlnt load track " + fname);
                }
            }
            files = Directory.GetFiles(path, "*.xml", scanRecusive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            track = null;
            foreach (String fname in files)
            {
                try
                {
                    track = Track.Load(fname);
                    if (!db.Contains(track))
                        db.Add(track);
                }
                catch (Exception)
                {
                    //                    System.Console.WriteLine("Coudlnt load track " + fname);
                }
            }
        }

        #region ITrackServer Member
        /// <summary>
        /// A dictionary containing all present tracks
        /// </summary>
        /// <returns>[...]</returns>
        public Dictionary<int, TrackInfo> GetTrackInfos()
        {
            Dictionary<int, TrackInfo> res = new Dictionary<int, TrackInfo>();
            int idx=0;
            foreach (Track track in db)
                res.Add(idx++, track.TrackInfo);
            return res;
        }

        /// <summary>
        /// Retrieve a single track based on the index stored in the dictionary
        /// </summary>
        /// <param name="idx">track index</param>
        /// <returns>[...]</returns>
        public Track GetTrack(int idx)
        {
            return db[idx];
        }

        /// <summary>
        /// Add a track to server instance - no storing
        /// </summary>
        /// <param name="track">the track</param>
        /// <returns>the index of the added track</returns>
        public int AddTrack(Track track)
        {
            db.Add(track);
            return db.Count - 1;
        }

        /// <summary>
        /// Store a track on the server.
        /// </summary>
        /// <param name="track">track</param>
        /// <param name="fname">base filename</param>
        /// <returns>success</returns>
        public bool StoreTrack(Track track, String fname)
        {
            try
            {
                Track.Save(path + "\\" + fname, track);
                return true;
            }
            catch (Exception)
            {
//                System.Console.WriteLine("Couldnt write track: " + fname);    
            }
            return false;
        }
        #endregion
    }
}
